// Copyright 2021 ByteDance Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build ignore
// +build ignore

package main

import (
	"bytes"
	"go/format"
	"io/ioutil"
	"os"
	"strings"
)

var lengthFunction = `func (s Int64Set) Len() int {
	return len(s)
}`

func main() {
	f, err := os.Open("hashset.go")
	if err != nil {
		panic(err)
	}
	filedata, err := ioutil.ReadAll(f)
	if err != nil {
		panic(err)
	}
	w := new(bytes.Buffer)
	w.WriteString(`// Copyright 2021 ByteDance Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by go run types_gen.go; DO NOT EDIT.` + "\r\n\n")
	start_pos := strings.Index(string(filedata), "package hashset")
	w.WriteString(string(filedata)[start_pos : start_pos+len("package hashset")])
	ts := []string{"Byte", "Complex64", "Complex128", "Float32", "Float64", "Int", "Int8", "Int16", "Int32", "Rune", "String", "Uint", "Uint8", "Uint16", "Uint32", "Uint64", "Uintptr"} // all types need to be converted

	for _, upper := range ts {
		lower := strings.ToLower(upper)
		data := string(filedata)
		// Remove header.
		data = data[start_pos+len("package hashset"):]
		// Remove the special case.
		data = strings.Replace(data, lengthFunction, "", -1)
		// Common cases.
		data = strings.Replace(data, "int64", lower, -1)
		data = strings.Replace(data, "Int64", upper, -1)
		if inSlice(lowerSlice(ts), lower) {
			data = strings.Replace(data, "length "+lower, "length int64", 1)
		}
		// Add the special case.
		data = data + strings.Replace(lengthFunction, "Int64Set", upper+"Set", 1)
		w.WriteString(data)
		w.WriteString("\r\n")
	}

	out, err := format.Source(w.Bytes())
	if err != nil {
		panic(err)
	}
	if err := ioutil.WriteFile("types.go", out, 0660); err != nil {
		panic(err)
	}
}

func lowerSlice(s []string) []string {
	n := make([]string, len(s))
	for i, v := range s {
		n[i] = strings.ToLower(v)
	}
	return n
}

func inSlice(s []string, val string) bool {
	for _, v := range s {
		if v == val {
			return true
		}
	}
	return false
}
